package View.Almacen.BloquearUbicacion;

import java.io.*;
import java.util.Random;

public class TSP{
            final int Length = 300;
            final int MAX = 300;
            final int tSize = 2;

            int Size=20;//20
            int Size2=8;//8
            int Source;
            int Step;
            int Count;
            int Node;
            int Node2;
            double Purity;
            Random rd;

            class RoutingClass{
                    int chromosome [] = new int[Length];
                    double fitness;
                    int size;
            }
            RoutingClass Routing [] = new RoutingClass [2*MAX];
            RoutingClass BestRoute= new RoutingClass();

            private int Connect[][] = new int[Length][Length];
            private int Connect2[][] = new int[Length][Length];
            private int Temp_Connect[][] = new int[Length][Length]; //Tempairly Confirm Connection
            
            class CostClass{
                    RoutingClass Routing = new RoutingClass();
                    int cost;
            }
            CostClass Cost[][] = new CostClass[Length][Length];
            private int Cost2[][] = new int[Length][Length]; 
            private double Mutation_rate;							//Mutation Rate

            public BufferedReader fin;
            public BufferedWriter fout;

            /////// To use Crossover Operation //////
            private class Cross{
                    int x;
                    int y;
            }
            private Cross cross[] = new Cross[MAX];

            private class TRouting{
                    int chromosome[] = new int[Length];
                    int size;
            }
            private TRouting tRouting[] = new TRouting[tSize];

            
            int arrUbi[];
            ///
            TSP(int cost[][],int numCost,int arrUbi[],int numUbi, int source,int p1[][]){

                    
                
                    for (int i=0;i<2*MAX;i++){
                        Routing[i]=new RoutingClass();
                    }
                    for (int i=0;i<MAX;i++){
                        cross[i]= new Cross();
                    }
                    for (int i=0;i<tSize;i++){
                        tRouting[i]=new TRouting();
                    }
                    for (int i=0;i<Length;i++)
                        for (int j=0;j<Length;j++)
                            Cost[i][j]=new CostClass();
                    
                    rd = new Random(System.currentTimeMillis());    
                    
                    Mutation_rate = 0.1;
                    Source = source;
                    
                    //de entrada
                    for (int i=0;i<numCost;i++)
                        for (int j=0;j<numCost;j++){
                            Cost2[i][j]=cost[i][j];
                            if (Cost2[i][j]==0)
                                Connect2[i][j]=0;
                            else Connect2[i][j]=1;
                        }
                    Node2=numCost;
                    Node=numUbi;
                    this.arrUbi=arrUbi;
                    
                    for (int i=0;i<Size/2;i++){
                        Routing[i].chromosome=p1[i];
                    }

            };

            int iRandom(int num){
                    int temp = rd.nextInt(num);
                    return temp;
            }      // int Random generator

            double dRandom()
            {
                    double temp = rd.nextDouble();
                    return temp;
            }   // Double Random generator
            /////// Initionalize Population ////////

            void Init(){
                    int i,j,flag;

                    //lleno la tabla de coneccion
                    for (i=0;i<Node;i++)
                        for (j=0;j<Node;j++){
                            Cost[i][j].cost=0;
                            if (i==j)
                                Connect[i][j]=0;
                            else
                                Connect[i][j]=1;
                        }
                    Connect[0][0]=0;
                    
                            
                    
                    
                    
                    Count = 0;
                    

                    for(i=Size/2;i<Size;i++)
                            Population(i);
                    while(true)
                    {
                            flag = Convergence();

                            //mejorRuta
                            int bestPosition=0,m;
                            for (m=1; m<Size;m++)
                            {
                                if (Routing[m].fitness>Routing[bestPosition].fitness){
                                    bestPosition=m;
                                }
                            }
                            if (Routing[bestPosition].fitness>BestRoute.fitness)
                            {
                                BestRoute.fitness=Routing[bestPosition].fitness;
                                for (m=0; m<Node;m++)
                                    BestRoute.chromosome[m]=Routing[bestPosition].chromosome[m];
                            }
                            //fin mejor rura

                            if(flag == 0)
                                    break;
                    }
                    Print();

                    try{
                        fout.close();
                    }catch(Exception e){}
            }

            void TTemp(int chromosome_number){
                    for(int i=0;i<Node;i++)
                    {
                            Routing[chromosome_number].chromosome[i] = 0;
                            for(int j=0;j<Node;j++)
                                    Temp_Connect[i][j] = Connect[i][j];
                    }
            }

            void Population(int chromosome_number){
                    int temp=0,locus;
                    int length=0;
                    TTemp(chromosome_number);
                    int T[] = new int[Length];
                    locus=T[length]=Source; length++;
                    for(int j=1;j<Node;j++)
                    {
                            temp = pLocation(locus);
                            if(temp != -1)
                            {
                                    T[length]=temp;length++;
                                    Delete_Path(locus);
                                    locus = temp;
                            }
                            if(length == Node)
                            {
                                    int i;
                                    for(i=0;i<length;i++)
                                            Routing[chromosome_number].chromosome[i] = T[i];
                                    break;
                            }
                    }
            } // Make Random Population

            int pLocation(int locus){
                    int temp;
                    //contar conectividades;
                    int cont=0;
                    for (int i=0;i<Node;i++){
                        if (Temp_Connect[locus][i]==1)
                            cont++;
                    }
                    if (cont==0)
                        return -1;

                    temp = iRandom(cont);
                    int j=-1;
                    for (int i=0;i<Node;i++){
                        if (Temp_Connect[locus][i]==1)
                            j++;
                        if (j==temp)
                            return i;
                    }
                    return -1;
            }



            void Delete_Path(int locus)
            {
                    for(int i=0;i<Node;i++)
                    {
                            Temp_Connect[i][locus] = Temp_Connect[locus][i] = 0 ;
                    }
            }

            /////// Fitness Function ///////////
            void Fitness_Function()
            {
                    int temp;
                    for(int i=0;i<Size;i++)
                    {
                            temp = 0;
                            for(int j=1;j<Node;j++)
                            {
                                if (Cost[Routing[i].chromosome[j-1]][Routing[i].chromosome[j]].cost==0)
                                {
                                    //VRP vrp=new VRP(Connect2,Cost2,Node2,Size,arrUbi[j-1],arrUbi[j]);
                                    VRP vrp=new VRP(Connect2,Cost2,Node2,Size2,arrUbi[Routing[i].chromosome[j-1]],arrUbi[Routing[i].chromosome[j]]);
                                    VRP.RoutingClass intermedio=vrp.Init();
                                    Cost[Routing[i].chromosome[j-1]][Routing[i].chromosome[j]].Routing.chromosome=intermedio.chromosome;
                                    Cost[Routing[i].chromosome[j-1]][Routing[i].chromosome[j]].Routing.size=intermedio.size;
                                    //20070263 no es necesario el routing.fitness
                                    Cost[Routing[i].chromosome[j-1]][Routing[i].chromosome[j]].Routing.fitness=intermedio.fitness;
                                    Cost[Routing[i].chromosome[j-1]][Routing[i].chromosome[j]].cost=(int)(1/intermedio.fitness);
                                    
                                    
                                    int auxChromo[]=new int[intermedio.size];
                                    int fin=intermedio.size-1;
                                    for (int ii=0;ii<intermedio.size;ii++){
                                        auxChromo[fin]=intermedio.chromosome[ii];
                                        fin--;
                                    }                                  
                                    
                                    
                                    Cost[Routing[i].chromosome[j]][Routing[i].chromosome[j-1]].Routing.chromosome=auxChromo;
                                    Cost[Routing[i].chromosome[j]][Routing[i].chromosome[j-1]].Routing.size=intermedio.size;
                                    //20070263 no es necesario el routing.fitness
                                    Cost[Routing[i].chromosome[j]][Routing[i].chromosome[j-1]].Routing.fitness=intermedio.fitness;
                                    Cost[Routing[i].chromosome[j]][Routing[i].chromosome[j-1]].cost=(int)(1/intermedio.fitness);
                                }
                                temp += Cost[Routing[i].chromosome[j-1]][Routing[i].chromosome[j]].cost;
                            }
                            if (Cost[Routing[i].chromosome[Node-1]][Routing[i].chromosome[0]].cost==0)
                            {
                                //VRP vrp=new VRP(Connect2,Cost2,Node2,Size,arrUbi[0],arrUbi[Node-1]);
                                
                                VRP vrp=new VRP(Connect2,Cost2,Node2,Size2,arrUbi[Routing[i].chromosome[Node-1]],arrUbi[Routing[i].chromosome[0]]);
                                VRP.RoutingClass intermedio=vrp.Init();
                                Cost[Routing[i].chromosome[Node-1]][Routing[i].chromosome[0]].Routing.chromosome=intermedio.chromosome;
                                Cost[Routing[i].chromosome[Node-1]][Routing[i].chromosome[0]].Routing.size=intermedio.size;
                                //20070263 no es necesario el routing.fitness
                                Cost[Routing[i].chromosome[Node-1]][Routing[i].chromosome[0]].Routing.fitness=intermedio.fitness;
                                Cost[Routing[i].chromosome[Node-1]][Routing[i].chromosome[0]].cost=(int)(1/intermedio.fitness);
                                
                                int auxChromo[]=new int[intermedio.size];
                                int fin=intermedio.size-1;
                                for (int ii=0;ii<intermedio.size;ii++){
                                    auxChromo[fin]=intermedio.chromosome[ii];
                                    fin--;
                                }            
                                
                                
                                Cost[Routing[i].chromosome[0]][Routing[i].chromosome[Node-1]].Routing.chromosome=auxChromo;
                                Cost[Routing[i].chromosome[0]][Routing[i].chromosome[Node-1]].Routing.size=intermedio.size;
                                //20070263 no es necesario el routing.fitness
                                Cost[Routing[i].chromosome[0]][Routing[i].chromosome[Node-1]].Routing.fitness=intermedio.fitness;
                                Cost[Routing[i].chromosome[0]][Routing[i].chromosome[Node-1]].cost=(int)(1/intermedio.fitness);
                            }
                            temp+=Cost[Routing[i].chromosome[Node-1]][Routing[i].chromosome[0]].cost;
                            Routing[i].fitness = 1/(temp*1.0);
                    }
            }

            /////// Tournament Selection //////////
            void Shuffle()
            {
                    int temp1, temp2;
                    for(int i=0; i<Size; i++ )
                    {
                            temp1 = iRandom(Size);temp2 = iRandom(Size);
                            Exchange(temp1,temp2);
                    }
            }

            void Exchange(int first, int second)
            {
                    Routing[MAX] = Routing[first];
                    Routing[first] = Routing[second];
                    Routing[second] = Routing[MAX];
            }
            void Tournament_Selection()
            {
                    int i;
                    Shuffle();
                    for(i=0;i<Size/2;i++)
                            Max(i,Size/2+i);
                    for(i=0;i<Size;i++)
                            Routing[i] = Routing[MAX+i];
                    Count = 0;
            }

            void Max(int first,int second)
            {
                    int temp = iRandom(Size);
                    if(Routing[first].fitness >= Routing[second].fitness)
                            Routing[MAX+Count] = Routing[first];
                    else
                            Routing[MAX+Count] = Routing[second];
                    Count++;
                    Routing[MAX+Count] = Routing[temp];
                    Count++;
            }

            ////// Detect Convergence ////
            int Convergence()
            {
                    int flag=0;
                    Fitness_Function();
                    Tournament_Selection();
                    for(int i=1;i<Size;i++)
                    {
                            if(Routing[0].fitness != Routing[i].fitness)
                            {
                                            flag++;
                                            break;
                            }
                    }
                    if(flag != 0)
                    {
                            Crossover();
                            Mutuation();
                    }
                    return flag;
            }
            void Crossover()
            {
                //seleccion de padres
                double porcentaje []=new double [Size],total=0;
                int padre=0,madre=0;

                for (int i=0;i<Size;i++)
                {
                    total+=porcentaje[i]=Routing[i].fitness;
                }
                for (int i=0;i<Size;i++)
                {
                    porcentaje[i]=porcentaje[i]/total*100;
                }
                for (int i=Size-1;i>=0;i--)
                {
                    for (int j=i-1;j>=0;j--)
                        porcentaje[i]+=porcentaje[j];
                }


                total= iRandom(100);
                for (int i=0;i<Size;i++)
                {
                    if (total<porcentaje[i])
                    {
                        padre=i;
                        break;
                    }
                }
                total= iRandom(100);
                for (int i=0;i<Size;i++)
                {
                    if (total<porcentaje[i])
                    {
                        madre=i;
                        break;
                    }
                }
                // Fin seleccion de padres

                //cruce //que miedo
                //padre busco a izqierda, madre a derecha
                int p=iRandom(Node),m=0;
                for (int i=0;i<Node;i++)
                {
                    if (Routing[madre].chromosome[i]==Routing[padre].chromosome[p])
                    {
                        m=i;
                        break;
                    }
                }
                int contIzq=0, contDer=1;
                int izq[]=new  int[Node];
                int der[]=new  int[Node];
                der[0]=Routing[padre].chromosome[p];
                boolean izqContinuar=true,derContinuar=true;
                while (izqContinuar && derContinuar)
                {                        
                    if (izqContinuar==true){
                        p--;
                        if (p<0){
                            p=Node-1;
                        }

                        //verifico validez
                        for (int i=0;i<contIzq;i++)
                        {
                            if (Routing[padre].chromosome[p]==izq[i]){
                                izqContinuar=false;
                                break;
                            }
                        }
                        for (int i=0;i<contDer;i++)
                        {
                            if (Routing[padre].chromosome[p]==der[i]){
                                izqContinuar=false;
                                break;
                            }
                        }
                        //end verifico validez

                        if (izqContinuar==true)
                        {
                            izq[contIzq]=Routing[padre].chromosome[p];
                            contIzq++;
                        }
                    }
                    if (derContinuar==true){
                        m++;
                        if (m==Node){
                            m=0;
                        }

                        //verifico validez
                        for (int i=0;i<contIzq;i++)
                        {
                            if (Routing[madre].chromosome[m]==izq[i]){
                                derContinuar=false;
                                break;
                            }
                        }
                        for (int i=0;i<contDer;i++)
                        {
                            if (Routing[madre].chromosome[m]==der[i]){
                                derContinuar=false;
                                break;
                            }
                        }
                        //end verifico validez

                        if (derContinuar==true)
                        {
                            der[contDer]=Routing[madre].chromosome[m];
                            contDer++;
                        }
                    }


                }
                RoutingClass hijo= new RoutingClass();
                //copio lo de la izquierda a hijo
                for (int i=contIzq,j=0;i<contIzq+contDer;i++,j++)
                {
                    hijo.chromosome[i]=der [j];                            
                }                         

                //copio lo de la derecha a hijo
                for (int i=contIzq-1,j=0;i>=0;i--,j++)
                {
                    hijo.chromosome[j]=izq [i];                            
                }

                //20070263 puede mejorarse
                //lleno aleatoriamente
                for (int i=contIzq+contDer;i<Node;i++){
                    int temp=0;
                    boolean again=true;
                    while (again)
                    {
                        again=false;
                        temp=iRandom(Node);
                        //verifico validez
                        for (int j=0;j<i;j++)
                        {
                          if (temp==hijo.chromosome[j])
                          {
                              again=true;
                              break;
                          }                                      
                        }
                        if (again==false){
                          hijo.chromosome[i]=temp;
                          break;
                        }                              
                    }                      
                }
                int temp = 0;
                
                //copiado de funcion fitness
                for(int j=1;j<Node;j++)
                {
                    if (Cost[hijo.chromosome[j-1]][hijo.chromosome[j]].cost==0)
                    {
                        //VRP vrp=new VRP(Connect2,Cost2,Node2,Size,arrUbi[j-1],arrUbi[j]);
                        VRP vrp=new VRP(Connect2,Cost2,Node2,Size2,arrUbi[hijo.chromosome[j-1]],arrUbi[hijo.chromosome[j]]);
                        VRP.RoutingClass intermedio=vrp.Init();
                        Cost[hijo.chromosome[j-1]][hijo.chromosome[j]].Routing.chromosome=intermedio.chromosome;
                        Cost[hijo.chromosome[j-1]][hijo.chromosome[j]].Routing.size=intermedio.size;
                        //20070263 no es necesario el routing.fitness
                        Cost[hijo.chromosome[j-1]][hijo.chromosome[j]].Routing.fitness=intermedio.fitness;
                        Cost[hijo.chromosome[j-1]][hijo.chromosome[j]].cost=(int)(1/intermedio.fitness);
                        
                        int auxChromo[]=new int[intermedio.size];
                        int fin=intermedio.size-1;
                        for (int ii=0;ii<intermedio.size;ii++){
                            auxChromo[fin]=intermedio.chromosome[ii];
                            fin--;
                        }            
                        
                        
                        Cost[hijo.chromosome[j]][hijo.chromosome[j-1]].Routing.chromosome=auxChromo;
                        Cost[hijo.chromosome[j]][hijo.chromosome[j-1]].Routing.size=intermedio.size;
                        //20070263 no es necesario el routing.fitness
                        Cost[hijo.chromosome[j]][hijo.chromosome[j-1]].Routing.fitness=intermedio.fitness;
                        Cost[hijo.chromosome[j]][hijo.chromosome[j-1]].cost=(int)(1/intermedio.fitness);
                    }
                    temp += Cost[hijo.chromosome[j-1]][hijo.chromosome[j]].cost;
                }
                if (Cost[hijo.chromosome[Node-1]][hijo.chromosome[0]].cost==0)
                {
                    //VRP vrp=new VRP(Connect2,Cost2,Node2,Size,arrUbi[0],arrUbi[Node-1]);
                    VRP vrp=new VRP(Connect2,Cost2,Node2,Size2,arrUbi[hijo.chromosome[Node-1]],arrUbi[hijo.chromosome[0]]);
                    VRP.RoutingClass intermedio=vrp.Init();
                    Cost[hijo.chromosome[Node-1]][hijo.chromosome[0]].Routing.chromosome=intermedio.chromosome;
                    Cost[hijo.chromosome[Node-1]][hijo.chromosome[0]].Routing.size=intermedio.size;
                    //20070263 no es necesario el routing.fitness
                    Cost[hijo.chromosome[Node-1]][hijo.chromosome[0]].Routing.fitness=intermedio.fitness;
                    Cost[hijo.chromosome[Node-1]][hijo.chromosome[0]].cost=(int)(1/intermedio.fitness);
                    
                    int auxChromo[]=new int[intermedio.size];
                    int fin=intermedio.size-1;
                    for (int ii=0;ii<intermedio.size;ii++){
                        auxChromo[fin]=intermedio.chromosome[ii];
                        fin--;
                    }           
                    
                    Cost[hijo.chromosome[0]][hijo.chromosome[Node-1]].Routing.chromosome=auxChromo;
                    Cost[hijo.chromosome[0]][hijo.chromosome[Node-1]].Routing.size=intermedio.size;
                    //20070263 no es necesario el routing.fitness
                    Cost[hijo.chromosome[0]][hijo.chromosome[Node-1]].Routing.fitness=intermedio.fitness;
                    Cost[hijo.chromosome[0]][hijo.chromosome[Node-1]].cost=(int)(1/intermedio.fitness);
                }
                temp+=Cost[hijo.chromosome[Node-1]][hijo.chromosome[0]].cost;
                //end copiado de funcion fitness
                
                hijo.fitness = 1/(temp*1.0);


                //ahora busco el peor fitness para reemplazarlo
                int peorFitness=0;
                for (int i=1;i<Size;i++)
                    if ((1/Routing[i].fitness)>(1/Routing[peorFitness].fitness))
                        peorFitness=i;
                
                if (hijo.fitness>Routing[peorFitness].fitness)                    
                    Routing[peorFitness]=hijo;
            }
            void Mutuation()
            {
                for (int i=0;i<Size;i++)
                {
                    if (dRandom()<Mutation_rate){
                        int start,end,temp2;
                        start=iRandom(Node);
                        end=iRandom(Node);

                        //me aseguro que fin sea mayor a ini
                        if (end<start){
                            temp2=end;
                            end=start;
                            start=temp2;
                        }
                        temp2=Routing[i].chromosome[end];
                        for (int j=end-1;j>=start;j--)
                        {
                            Routing[i].chromosome[j+1]=Routing[i].chromosome[j];
                        }
                        Routing[i].chromosome[start]=temp2;      
                        
                        
                        int temp = 0;
                
                        //copiado de funcion fitness
                        for(int j=1;j<Node;j++)
                        {
                            if (Cost[Routing[i].chromosome[j-1]][Routing[i].chromosome[j]].cost==0)
                            {
                                //VRP vrp=new VRP(Connect2,Cost2,Node2,Size,arrUbi[j-1],arrUbi[j]);
                                VRP vrp=new VRP(Connect2,Cost2,Node2,Size2,arrUbi[Routing[i].chromosome[j-1]],arrUbi[Routing[i].chromosome[j]]);
                                VRP.RoutingClass intermedio=vrp.Init();
                                Cost[Routing[i].chromosome[j-1]][Routing[i].chromosome[j]].Routing.chromosome=intermedio.chromosome;
                                Cost[Routing[i].chromosome[j-1]][Routing[i].chromosome[j]].Routing.size=intermedio.size;
                                //20070263 no es necesario el routing.fitness
                                Cost[Routing[i].chromosome[j-1]][Routing[i].chromosome[j]].Routing.fitness=intermedio.fitness;
                                Cost[Routing[i].chromosome[j-1]][Routing[i].chromosome[j]].cost=(int)(1/intermedio.fitness);

                                int auxChromo[]=new int[intermedio.size];
                                int fin=intermedio.size-1;
                                for (int ii=0;ii<intermedio.size;ii++){
                                    auxChromo[fin]=intermedio.chromosome[ii];
                                    fin--;
                                }            


                                Cost[Routing[i].chromosome[j]][Routing[i].chromosome[j-1]].Routing.chromosome=auxChromo;
                                Cost[Routing[i].chromosome[j]][Routing[i].chromosome[j-1]].Routing.size=intermedio.size;
                                //20070263 no es necesario el routing.fitness
                                Cost[Routing[i].chromosome[j]][Routing[i].chromosome[j-1]].Routing.fitness=intermedio.fitness;
                                Cost[Routing[i].chromosome[j]][Routing[i].chromosome[j-1]].cost=(int)(1/intermedio.fitness);
                            }
                            temp += Cost[Routing[i].chromosome[j-1]][Routing[i].chromosome[j]].cost;
                        }
                        if (Cost[Routing[i].chromosome[Node-1]][Routing[i].chromosome[0]].cost==0)
                        {
                            //VRP vrp=new VRP(Connect2,Cost2,Node2,Size,arrUbi[0],arrUbi[Node-1]);
                            VRP vrp=new VRP(Connect2,Cost2,Node2,Size2,arrUbi[Routing[i].chromosome[Node-1]],arrUbi[Routing[i].chromosome[0]]);
                            VRP.RoutingClass intermedio=vrp.Init();
                            Cost[Routing[i].chromosome[Node-1]][Routing[i].chromosome[0]].Routing.chromosome=intermedio.chromosome;
                            Cost[Routing[i].chromosome[Node-1]][Routing[i].chromosome[0]].Routing.size=intermedio.size;
                            //20070263 no es necesario el routing.fitness
                            Cost[Routing[i].chromosome[Node-1]][Routing[i].chromosome[0]].Routing.fitness=intermedio.fitness;
                            Cost[Routing[i].chromosome[Node-1]][Routing[i].chromosome[0]].cost=(int)(1/intermedio.fitness);

                            int auxChromo[]=new int[intermedio.size];
                            int fin=intermedio.size-1;
                            for (int ii=0;ii<intermedio.size;ii++){
                                auxChromo[fin]=intermedio.chromosome[ii];
                                fin--;
                            }           

                            Cost[Routing[i].chromosome[0]][Routing[i].chromosome[Node-1]].Routing.chromosome=auxChromo;
                            Cost[Routing[i].chromosome[0]][Routing[i].chromosome[Node-1]].Routing.size=intermedio.size;
                            //20070263 no es necesario el routing.fitness
                            Cost[Routing[i].chromosome[0]][Routing[i].chromosome[Node-1]].Routing.fitness=intermedio.fitness;
                            Cost[Routing[i].chromosome[0]][Routing[i].chromosome[Node-1]].cost=(int)(1/intermedio.fitness);
                        }
                        temp+=Cost[Routing[i].chromosome[Node-1]][Routing[i].chromosome[0]].cost;
                        //end copiado de funcion fitness

                        Routing[i].fitness = 1/(temp*1.0);
                        
                        
                        
                    }
                }

            }
            
            void Arreglar(){
                int aux;
                while (true){
                    if (BestRoute.chromosome[0]!=Source){
                        aux=BestRoute.chromosome[0];
                        for (int j=1;j<Node;j++)
                            BestRoute.chromosome[j-1]=BestRoute.chromosome[j];
                        BestRoute.chromosome[Node-1]=aux;
                    }
                    else 
                        break;
                
                }
            }
            
            void Print(){
                
                //pone 0 al inicio
                Arreglar();
                
                String cadena="Ruta optima:";
                
                for(int i=0;i<Node;i++){
                    cadena+=arrUbi[BestRoute.chromosome[i]]+" ";
                }
                cadena+="\nRecorrido: "+(1/BestRoute.fitness);
                
               javax.swing.JOptionPane jOP = new javax.swing.JOptionPane(); 
               
               
                //jOP.showMessageDialog(null,cadena);
                
                cadena+="\nRuta completa: ";
                
                                
                for(int i=0;i<Node-1;i++){
                    //fout << Routing[0].chromosome[i] <<" ";
                    for (int j=0;j<Cost[BestRoute.chromosome[i]][BestRoute.chromosome[i+1]].Routing.size-1;j++){
                        cadena+=Cost[BestRoute.chromosome[i]][BestRoute.chromosome[i+1]].Routing.chromosome[j]+"-";
                    }
                    
                }          
                for (int j=Cost[BestRoute.chromosome[0]][BestRoute.chromosome[Node-1]].Routing.size-1;j>0;j--){
                        cadena+=Cost[BestRoute.chromosome[0]][BestRoute.chromosome[Node-1]].Routing.chromosome[j]+"-";
                }
                cadena+=Cost[BestRoute.chromosome[0]][BestRoute.chromosome[Node-1]].Routing.chromosome[0];
                
                
                
                jOP.showMessageDialog(null,cadena); 
                //System.out.print(cadena+"\n");


            }


            ///// Everything Init ////
            void Routing_Init(){
                    for(int i=0;i<Size*2;i++)
                    {
                            Routing[i].fitness = 0.0;
                            for(int j=0;j<Length;j++)
                                    Routing[i].chromosome[j] = 0;
                    }
            }
	
}
